﻿using Desktop.Interfaces;
using System;
using System.ComponentModel;
using System.Runtime.Serialization;

namespace Desktop.Library
{
    public interface IContentItem : ISerializable, INotifyPropertyChanged, ICloneable<IContentItem>
    {
    }

    public interface IContentItem<T> : IContentItem
        where T: class, IContentItem<T>
    {
    }

    /// <summary>
    /// A story component.
    /// </summary>
    [Serializable()]
    public abstract class ContentItem<T> : IContentItem<T>
        where T : class, IContentItem<T>
    {
        #region Events

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Variables

        private DateTime _createdDate;
        private DateTime _lastModifiedDate;

        #endregion

        #region Constructors

        public ContentItem()
        {
            CreatedDate = DateTime.Now;
            LastModifiedDate = DateTime.Now;
        }

        public ContentItem(ContentItem<T> contentItem)
        {
            if (contentItem == null)
            {
                return;
            }
            CreatedDate = contentItem.CreatedDate;
            LastModifiedDate = contentItem.LastModifiedDate;
        }

        public ContentItem(SerializationInfo info, StreamingContext context)
        {
            CreatedDate = info.GetDateTime("CreatedDate");
            LastModifiedDate = info.GetDateTime("LastModifiedDate");
        }

        #endregion

        #region Properties

        public DateTime CreatedDate
        {
            get
            {
                return _createdDate;
            }
            internal set
            {
                if (_createdDate != value)
                {
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("CreatedDate"));
                    }
                }
                _createdDate = value;
            }
        }

        public DateTime LastModifiedDate
        {
            get
            {
                return _lastModifiedDate;
            }
            private set
            {
                if (_lastModifiedDate != value)
                {
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("LastModifiedDate"));
                    }
                }
                _lastModifiedDate = value;
            }
        }

        #endregion

        #region Methods

        public abstract override string ToString();

        public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            LastModifiedDate = DateTime.Now;
            info.AddValue("CreatedDate", CreatedDate);
            info.AddValue("LastModifiedDate", LastModifiedDate);
        }

        protected void PropertyHasChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public IContentItem Clone()
        {
            return Activator.CreateInstance(typeof(T), new object[] { this }) as T;
        }

        object ICloneable.Clone()
        {
            return Activator.CreateInstance(typeof(T), new object[] { this }) as T;
        }

        #endregion
    }
}
